if (!window.jQuery) {
  var jq = document.createElement('script'); jq.type = 'text/javascript';
  // Path to jquery.js file, eg. Google hosted version
  jq.src = '//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js';
  document.getElementsByTagName('head')[0].appendChild(jq);
}

$(function() {

  var sz_state = {
    // State variables
    loaded : false,
    loggedin : false,
    location_marked : false,
    location_url : window.location.href,

    // Data section
    conversations: [],
    conversation_map: {},

    check_login : function() {
      // Check that api access credentials are present
      if (typeof sz_user_guid !== 'undefined' && sz_user_guid && typeof sz_access_token !== 'undefined' && sz_access_token) {
       this.loggedin = true;
      }
    },
    load : function() {
      this.check_login();
      if (this.loggedin) {
        $.get(sz_authUrl("/api/state?url=" + encodeURIComponent(this.location_url)))
        .done(function(data) {
          console.log("Got state", data);
          sz_state.location_marked = data.location.marked;
          sz_state.conversations = data.conversations;
          sz_state.top_notes = data.top_notes;

          // remap conversations by id
          sz_state.conversation_map = _.object(_.map(sz_state.conversations, function(item) {
            return [item.id, item]
          }));

          console.log(sz_state.conversation_map);

          sz_updateUI(); 

          sz_state.loaded = true;
      })
      .fail(function(res) {
        console.error("No status", res);
        if(res.status == 401) {
          sz_state.loggedin = false;
        }
      });
      }
    },
    getConversation: function(cnv_id) {
      return this.conversation_map[cnv_id];
    },
    // Action section
    pending_actions : [],
    // action constants
    ADD_NOTE : "an",
    act : function(type, data) {
      this.pending_actions.push({'type':type, 'data':data});
      for (var i = this.pending_actions.length - 1; i >= 0; i--) {
        this.send(this.pending_actions[i]);
      };
    },
    send : function(action) {
      $.post("http://127.0.0.1:3000/api/act?user_guid=" + sz_user_guid + "&access_token=" + sz_access_token, {
        action : action
      })
      .done(function(data) {
        console.log("send successful", data);
      })
      .fail(function(res) {
        console.log("send failed", res);
      });
    },
    flag : function() {
      // toggle flag on current location
      this.location_marked = !this.location_marked;
      $.post("http://127.0.0.1:3000/api/locations?user_guid=" + sz_user_guid + "&access_token=" + sz_access_token, {
        title : document.title,
        url : sz_state.location_url,
        marked : sz_state.location_marked,
        faviconUrl : sz_getFavicon()
      })
      .done(function(data) {
        console.log("location added", data);
        sz_updateUI();
      })
      .fail(function(res) {
        console.log("error while adding location", res);
      });
    },
    add_note : function(note_text) {
      //this.act(this.ADD_NOTE, {'text':note_text, 'url':this.location_url});
      $.post("http://127.0.0.1:3000/api/notes?user_guid=" + sz_user_guid + "&access_token=" + sz_access_token, {
        text:note_text
      })
      .done(function(data) {
        console.log("send successful", data);
      })
      .fail(function(res) {
        console.log("send failed", res);
      });
    },
    add_cnv : function(cnv_title, note_text) {
      if (!cnv_title) return;
      //this.act(this.ADD_NOTE, {'text':note_text, 'url':this.location_url});
      $.post("http://127.0.0.1:3000/api/conversations?user_guid=" + sz_user_guid + "&access_token=" + sz_access_token, {
        title: cnv_title,
        text:note_text
      })
      .done(function(data) {
        console.log("send successful", data);
      })
      .fail(function(res) {
        console.log("send failed", res);
      });
    },
    // UI section
    paneOpen: false,
    active_panel:null,
    
    close_active_panel : function() {
      if (sz_state.active_panel) {
        sz_state.active_panel.close();
      }
    },
  }

  sz_state.load();

  // //////////////////////////////////////////////
  // MODEL

  function sz_authUrl(url) {
    var domain = "http://127.0.0.1:3000";
    var credentials = "user_guid=" + sz_user_guid + "&access_token=" + sz_access_token;

    if (url.indexOf("?") !== -1) {
      return domain + url + "&" + credentials;
    } else {
      return domain + url + "?" + credentials;
    }
  }

  
  // //////////////////////////////////////////////
  // CONTROLLER


  // New note panel
  var szNewNotePanel = {
    active : false,
    open : function() {
      if (!this.active) {
        sz_state.active_panel = this;
        this.active = true;

        $("#szNewNoteAction").addClass("active");
        $("#szNewNotePanel").show(50);
        $("#szPanelConversationsEmpty").hide();
      }
    },
    close : function() {
      sz_state.active_panel = null;
      this.active = false;
      $("#szNewNoteAction").removeClass("active"); 
      $("#szNewNotePanel").hide(50);
    }
  }

  // New note panel
  var szNewConversationPanel = {
    active : false,
    open : function() {
      if (!this.active) {
        sz_state.active_panel = this;
        this.active = true;

        $("#szNewCnvAction").addClass("active");
        $("#szNewCnvPanel").show(50);
      }
    },
    close : function() {
      sz_state.active_panel = null;
      this.active = false;
      $("#szNewCnvAction").removeClass("active"); 
      $("#szNewCnvPanel").hide(50);
    }
  }

  // Active conversation panel
  
  function sz_hide_active_cnv_panel() {
    if (sz_state.inConversation) {
      sz_state.inConversation = false;
      var cnv_id = $("#szPanelActiveConversation").data('active-conversation-id');
      $("#szPanelActiveConversation").hide(50, function() {
        $("#szActiveConversationNote").hide();
        $("#szConversation_"+cnv_id).show(20);  
      });
    }
  }

  function sz_hide_mark_panel() {
    $('#szMarkPanel').hide();
  }

  function sz_hide_search_panel() {
    $('#szSearchPanel').hide();
  }

  function sz_hide_all_panels() {
    sz_hide_search_panel();
    sz_hide_mark_panel();
    sz_hide_active_cnv_panel();
  }

  function activateConversation(cnv_id) {
    sz_state.close_active_panel();

    var cnv = sz_state.getConversation(cnv_id);
    if (sz_state.inConversation) {
      sz_hide_active_cnv_panel();
    }
    
    sz_state.inConversation = true;

    $("#szPanelActiveConversation").data('active-conversation-id', cnv_id);
    $("#szActiveConversationTitle").text(cnv.title);

    if (cnv.participants) {
      $("#szActiveConversationParticipants").empty();
      for (i = 0; i < cnv.participants.length; i++) {
        var participant = cnv.participants[i];
        // TODO: Think of a better way to load this html, maybe from server?

        $("#szActiveConversationParticipants").append(
          "<div class='sz_active_conversation_participant' data-item-id='"+participant.id+"'>"+
            "<img src='http://127.0.0.1:3000/images/default_participant.png' title='"+participant.label+"'></img>"+
          "</div>");
        
      }
    }

    if (cnv.notes) {
      $("#szActiveConversationNotes").empty();
      for (i = 0; i < cnv.notes.length; i++) {
        var note = cnv.notes[i];
        // TODO: Think of a better way to load this html, maybe from server?

        $("#szActiveConversationNotes").append("<div class='sz_note_item' data-item-id='"+note.id+"'>" +
                                            "<div class='sz_note_author'>" +
                                              "<b>"+note.authorLabel+"</b>" +
                                            "</div>" +
                                            "<div class='sz_note_fuzzy_date'>" +
                                              "2 days ago" +
                                            "</div>" +
                                            "<div style='clear:both'></div>" +
                                            "<div class='sz_note_text'>" +
                                                note.text + 
                                            "</div>" +
                                          "</div>");
        
      }
    }

    $("#szPanelActiveConversation").show(50);  
  }

  function sz_renderConversations() {
    if (sz_state.conversations.length > 0) {
      $("#szPanelConversationsEmpty").hide();
    }


    for (i = 0; i < sz_state.conversations.length; i++) {
      // TODO: Unbelievably ugly hack for time zone offset, should do something about this
      // https://github.com/sequelize/sequelize/issues/1035#issuecomment-27703435
      var cnv = sz_state.conversations[i];
      var temp_date = new Date(cnv.started)
      var cnv_date = prettyDate(new Date(temp_date.getTime() - temp_date.getTimezoneOffset() * 60 * 1000).toISOString());

      console.log(cnv);

      // TODO: Think of a better way to load this html, maybe from server?
      $("#szPanelConversations").append(
        "<div class='sz_cnv_item' id='szConversation_" + cnv.id + "' data-item-id='" + cnv.id + "'>" +
        "<div class='sz_cnv_header'>" + 
          "<div class='sz_cnv_fuzzy_date'>" + "from: " + cnv_date +"</div>" +
          "<a class='sz_cnv_add_pal_action'  href='#'><img src='http://127.0.0.1:3000/images/cnv_add_pal.png'></img></a>" +
          "<a class='sz_cnv_add_note_action' href='#'><img src='http://127.0.0.1:3000/images/cnv_add_note.png'></img></a>" +
        "</div>" +
        "<div class='sz_clear'></div>" +
        "<div class='sz_cnv_pals'>" +
          "<img src='http://127.0.0.1:3000/images/cnv_default_pal.png'></img>" +
          "Private" +
        "</div>" +
        "<div class='sz_cnv_top_note'>" + sz_state.top_notes[cnv.id].text + "</div>" +
        "<div class='sz_cnv_footer'>" + 
        "<a class='sz_cnv_more_action'>more...</a>"+
        "</div>"+
      "</div>");
    }

    $(".sz_cnv_item").click(function(event) {
      var cnv_elm = $(event.target).closest('.sz_cnv_item');
      $(cnv_elm).hide(20);

      var cnv_id = cnv_elm.data('item-id');
      activateConversation(cnv_id);
    })
  }

  function sz_showLogin() {
    $("#szLoginLink").attr('href', sz_login_url);
    $("#szLogin").toggle();
  }
  

  // /////////////////////////////////////////////////
  // VIEW

  function sz_updateUI() {
    if (sz_state.location_marked) {
      $("#szFlagLocationAction").addClass("active");
    } else {
      $("#szFlagLocationAction").removeClass("active"); 
    }

    sz_renderConversations();
  }

  // Main pane //////////
  $("#szPane").hover( function () {
    $(this).data('timeout', setTimeout( function () {

      $("#szPane").animate({width:"300px"}, 500, function(){
        sz_state.paneOpen = true;
        $("#szPaneContent").show(50);
      });

    }, 1000));
  }, function () {
    if (!sz_state.paneOpen) {
      console.log("Clear timeout");
      clearTimeout($(this).data('timeout'));
    }
  });

  $("#szClosePaneAction").click(function() {
    sz_state.paneOpen = false;
    $("#szPaneContent").hide(10, function() {
      $("#szPane").animate({width:"10px"}, 500, function(){
      });  
    });
  });

  // Flag action ///////////////
  $("#szFlagLocationAction").click(function(event) {
    sz_state.flag();
    event.stopPropagation();
    return false;
  });

  $("#szSearchPanelAction").click(function(event) {
    sz_hide_all_panels();
    $("szSearchPanel").show();
  });

  // New note action ///////////////
  $("#szNewPaneAction").click(function(event) {
    sz_hide_active_cnv_panel();
    sz_hide_search_panel();
    sz_hide_mark_panel();
    szNewNotePanel.open();
    event.stopPropagation();
    return false;
  });

  $("#szCloseNewNotePanelAction").click(function(event) {
    szNewNotePanel.close();
    event.stopPropagation();
    return false;
  });

  $("#szNewNoteActionDone").click(function(event) {
    var text = $("#szNewNoteTextArea").val();
    sz_state.add_note(text);
  });

    // New conversation action ///////////////
  $("#szNewCnvAction").click(function(event) {
    sz_hide_active_cnv_panel();
    sz_state.close_active_panel();
    $("#szNewCnvParticipantsInput").autocomplete({source:["hello", "world"]})
    szNewConversationPanel.open();
    event.stopPropagation();
    return false;
  });

  $("#szNewCnvActionCancel").click(function(event) {
    szNewConversationPanel.close();
    event.stopPropagation();
    return false;
  });

  // Active conversation ///////////////
  $("#szsz_hide_active_cnv_panelPaneAction").click(function(event) {
    sz_hide_active_cnv_panel();
    event.stopPropagation();
    return false;
  });

  $("#szAddNoteActiveConversationPaneAction").click(function(event) {
    $("#szActiveConversationNote").show(50);
    event.stopPropagation();
    return false;
  });

  

  $("#szNewCnvActionDone").click(function(event) {
    var title = $("#szNewCnvTitleInput").val();
    var text = $("#szNewCnvTextArea").val();
    sz_state.add_cnv(title, text);

    sz_state.close_active_panel();
    sz_renderConversations();
  });




});

// AUX /////////////////////////////////////////////////

// Favicon /////////////////////////////////////////////////
// http://stackoverflow.com/questions/10282939/how-to-get-favicons-url-from-a-generic-webpage-in-javascript

function sz_getFavicon(){
  var favicon = undefined;
  var nodeList = document.getElementsByTagName("link");
  for (var i = 0; i < nodeList.length; i++)
  {
      if((nodeList[i].getAttribute("rel") == "icon")||(nodeList[i].getAttribute("rel") == "shortcut icon"))
      {
          favicon = nodeList[i].getAttribute("href");
      }
  }

  console.log("Got favicon", favicon);
  return favicon;
}


/*
 * JavaScript Pretty Date
 * Copyright (c) 2011 John Resig (ejohn.org)
 * Licensed under the MIT and GPL licenses.
 */

// Takes an ISO time and returns a string representing how
// long ago the date represents.
function prettyDate(time){
  var date = new Date((time || "").replace(/-/g,"/").replace(/[TZ]/g," ")),
    diff = (((new Date()).getTime() - date.getTime()) / 1000),
    day_diff = Math.floor(diff / 86400);
      
  if ( isNaN(day_diff) || day_diff < 0 || day_diff >= 31 )
    return;
      
  return day_diff == 0 && (
      diff < 60 && "just now" ||
      diff < 120 && "1 minute ago" ||
      diff < 3600 && Math.floor( diff / 60 ) + " minutes ago" ||
      diff < 7200 && "1 hour ago" ||
      diff < 86400 && Math.floor( diff / 3600 ) + " hours ago") ||
    day_diff == 1 && "Yesterday" ||
    day_diff < 7 && day_diff + " days ago" ||
    day_diff < 31 && Math.ceil( day_diff / 7 ) + " weeks ago";
}

// If jQuery is included in the page, adds a jQuery plugin to handle it as well
if ( typeof jQuery != "undefined" )
  jQuery.fn.prettyDate = function(){
    return this.each(function(){
      var date = prettyDate(this.title);
      if ( date )
        jQuery(this).text( date );
    });
  };
